// Author	: damphat@gmail.com
// Created	: 01/12/2008

#pragma once
#include "vn/Convert.h"
#include <tchar.h>
#include <stdio.h>

template <class T>
static void InternalWrite(T v) {
	_tprintf(_T("%s"), Convert::ToString(v).C_STR());
}

template<class T>
static void ReadLineAndConvert(T &out) {
	TChar buf[512];
	_getts(buf);
	Convert::To(out, buf);
}

class Console {
public:
	// OUTPUT FUNCTIONS
	static void Write(bool			val)	{ InternalWrite(val); }
	static void Write(Char			val)	{ InternalWrite(val); }
	static void Write(UChar			val)	{ InternalWrite(val); }
	static void Write(Short			val)	{ InternalWrite(val); }
	static void Write(UShort		val)	{ InternalWrite(val); }
	static void Write(WChar			val)	{ InternalWrite(val); }
	static void Write(Int			val)	{ InternalWrite(val); }
	static void Write(UInt			val)	{ InternalWrite(val); }
	static void Write(Long			val)	{ InternalWrite(val); }
	static void Write(ULong			val)	{ InternalWrite(val); }
	static void Write(Int64			val)	{ InternalWrite(val); }
	static void Write(UInt64		val)	{ InternalWrite(val); }
	static void Write(float			val)	{ InternalWrite(val); }
	static void Write(double		val)	{ InternalWrite(val); }
	static void Write(long double	val)	{ InternalWrite(val); }
	static void Write(String		val)	{ InternalWrite(val); }
	static void Write(LPCChar		val)	{ InternalWrite(val); } // add
	static void Write(LPCWChar		val)	{ InternalWrite(val); } // add
	static void Write(LPCVoid		val)	{ InternalWrite(val); }	// add
	// datetime
	// timespan

	// INPUT FUNCTIONS
	static void Read(bool			&out)	{ ReadLineAndConvert(out); }
	static void Read(Char			&out)	{ ReadLineAndConvert(out); }
	static void Read(UChar			&out)	{ ReadLineAndConvert(out); }
	static void Read(Short			&out)	{ ReadLineAndConvert(out); }
	static void Read(UShort			&out)	{ ReadLineAndConvert(out); }
	static void Read(WChar			&out)	{ ReadLineAndConvert(out); }
	static void Read(Int			&out)	{ ReadLineAndConvert(out); }
	static void Read(UInt			&out)	{ ReadLineAndConvert(out); }
	static void Read(Long			&out)	{ ReadLineAndConvert(out); }
	static void Read(ULong			&out)	{ ReadLineAndConvert(out); }
	static void Read(Int64			&out)	{ ReadLineAndConvert(out); }
	static void Read(UInt64			&out)	{ ReadLineAndConvert(out); }
	static void Read(float			&out)	{ ReadLineAndConvert(out); }
	static void Read(double			&out)	{ ReadLineAndConvert(out); }
	static void Read(long double	&out)	{ ReadLineAndConvert(out); }
	static void Read(String			&out)	{ out = ReadLine(); }
	// datetime
	// timespan

	template <class T>
	static void WriteLine(T v) {
		Write(v);
		WriteLine();
	}

	static void WriteLine() {
		Write(_T("\n"));
	}

	static int ReadKey() {
		return getchar();
	}

	static String ReadLine() {
		TChar buf[512];
		return _getts(buf);
	}

	template <size_t size>
	static void Read(Char (&buffer)[size]) {
		gets(buffer);
	}

	// how to call this function
	template <size_t size>
	static void Read(WChar (&buffer)[size]) {
		_getws(buffer);
	}

	template<class T>
	static T Read() {
		T out;
		Read(out);
		return out;
	}
};

// requirement:
// - method: int Keypressed()
